package com.davidhigenbottam.HeatMap.client;

import java.util.Comparator;

import com.davidhigenbottam.HeatMap.shared.Institution;
import com.davidhigenbottam.HeatMap.shared.Query;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class InstitutionTable {
	CellTable<Institution> cellTable = new CellTable<Institution>(Institution.NUMBER_OF_ROWS);
	ListDataProvider<Institution> dataProvider = new ListDataProvider<Institution>();
	TextColumn<Institution> nameColumn;
	TextColumn<Institution> valColumn;
	TextColumn<Institution> geocodedColumn;
	Query query;

	public InstitutionTable() {
		super();

		// Add a text column to show the name.
		nameColumn = new TextColumn<Institution>() {
			@Override
			public String getValue(Institution i) {
				return i.getName();
			}
		};
		nameColumn.setSortable(true);

		cellTable.addColumn(nameColumn, "Institution");

		valColumn = new TextColumn<Institution>() {
			@Override
			public String getValue(Institution i) {
				return i.getValueDescription();
			}
		};
		valColumn.setSortable(true);
		cellTable.addColumn(valColumn, "Value");
		
		geocodedColumn = new TextColumn<Institution>() {
			@Override
			public String getValue(Institution i) {
				return i.isGeocoded()?"yes":"no";
			}
		};
		geocodedColumn.setSortable(true);
		cellTable.addColumn(geocodedColumn, "Geocoded");
		
		
		dataProvider.addDataDisplay(cellTable);

		// Add a selection model to handle user selection.
		final SingleSelectionModel<Institution> selectionModel = new SingleSelectionModel<Institution>();

		cellTable.setSelectionModel(selectionModel);
		selectionModel
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					public void onSelectionChange(SelectionChangeEvent event) {
						Institution i = selectionModel.getSelectedObject();
						if (i != null) {
							 runInstitutionQuery(i.getName());
						}
					}
				});

	}
	
	public void runInstitutionQuery(String name){
		Window.alert("You selected: " + name);
//		query.setProvince(provinceName);
//		HeatMap.overlays.runInstitutionQuery(query);
	}

	public void addSortHandlers() {
		ListHandler<Institution> nameSortHandler = new ListHandler<Institution>(
				getDataProvider().getList());
		nameSortHandler.setComparator(getNameColumn(),
				InstitutionTable.getNameCamparator());
		getCellTable().addColumnSortHandler(nameSortHandler);

		ListHandler<Institution> valSortHandler = new ListHandler<Institution>(
				getDataProvider().getList());
		valSortHandler.setComparator(getValColumn(),
				InstitutionTable.getValueCamparator());
		getCellTable().addColumnSortHandler(valSortHandler);
		
		ListHandler<Institution> geocodedSortHandler = new ListHandler<Institution>(
				getDataProvider().getList());
		geocodedSortHandler.setComparator(getGeocodedColumn(),
				InstitutionTable.getGeocodeCamparator());
		getCellTable().addColumnSortHandler(geocodedSortHandler);
		
	}

	public CellTable<Institution> getCellTable() {
		return cellTable;
	}

	public void setCellTable(CellTable<Institution> cellTable) {
		this.cellTable = cellTable;
	}

	public ListDataProvider<Institution> getDataProvider() {
		return dataProvider;
	}

	public void setDataProvider(ListDataProvider<Institution> dataProvider) {
		this.dataProvider = dataProvider;
	}

	private static Comparator<Institution> nameCamparator = new Comparator<Institution>() {
		public int compare(Institution qd1, Institution qd2) {
			if (qd1 == qd2) {
				return 0;
			}
			// Compare the name columns.
			if (qd1 != null) {
				return (qd2 != null) ? qd1.getName().compareTo(qd2.getName()) : 1;
			}
			return -1;
		}
	};
	private static Comparator<Institution> valueCamparator = new Comparator<Institution>() {
		public int compare(Institution qd1, Institution qd2) {
			if (qd1 == qd2) {
				return 0;
			}
			// Compare the name columns.
			if (qd1 != null) {
				return (qd2 != null) ? Double.valueOf(qd1.getVal()).compareTo(
						Double.valueOf(qd2.getVal())) : 1;
			}
			return -1;
		}
	};
	private static Comparator<Institution> geocodCamparator = new Comparator<Institution>() {
		public int compare(Institution i1, Institution i2) {
			if (i1 == i2) {
				return 0;
			}
			// Compare the name columns.
			if (i1 != null && i2 !=null) {
				if(i1.isGeocoded()==i2.isGeocoded()){
					//if same then use value to order
					return Double.valueOf(i1.getVal()).compareTo(
							Double.valueOf(i2.getVal()));
				}
				else
					return Boolean.valueOf(i1.isGeocoded()).compareTo(i2.isGeocoded());
			}
			return 0;
		}
	};	
	

	public TextColumn<Institution> getNameColumn() {
		return nameColumn;
	}

	public void setNameColumn(TextColumn<Institution> nameColumn) {
		this.nameColumn = nameColumn;
	}

	public TextColumn<Institution> getValColumn() {
		return valColumn;
	}
	public TextColumn<Institution> getGeocodedColumn() {
		return geocodedColumn;
	}
	public void setValColumn(TextColumn<Institution> valColumn) {
		this.valColumn = valColumn;
	}

	public static Comparator<Institution> getNameCamparator() {
		return nameCamparator;
	}
	public static Comparator<Institution> getGeocodeCamparator() {
		return geocodCamparator;
	}
		

	public static void setNameCamparator(Comparator<Institution> nameCamparator) {
		InstitutionTable.nameCamparator = nameCamparator;
	}

	public static Comparator<Institution> getValueCamparator() {
		return valueCamparator;
	}

	public static void setValueCamparator(Comparator<Institution> valueCamparator) {
		InstitutionTable.valueCamparator = valueCamparator;
	}

	public void show() {
		cellTable.setVisible(true);
	}

	public void hide() {
		cellTable.setVisible(false);
	}

	public boolean isVisible(){
		return cellTable.isVisible();
	}
	public void setQuery(Query q) {
		this.query= q;
	}

}
